package com.gmall.product.controller;

import cn.hutool.crypto.digest.MD5;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.UploadFileRequest;
import com.gmall.common.result.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

@RestController
@RequestMapping("/admin/product")
public class FileUploadController
{

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    // 桶名称
    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    @Autowired
    OSS ossClientBuilder;
    @PostMapping("/fileUpload")
    public Result<String> uploadFile(MultipartFile file) throws IOException {

        // 文件上传的具体实现
        String fileName = file.getOriginalFilename();
        int lastIndex = fileName.lastIndexOf(".");

        String extName = fileName.substring(lastIndex);
        String file_md5 =  MD5.create().digestHex(file.getBytes());
        System.out.println("file_md5=" + file_md5 + extName);
        ossClientBuilder.putObject(bucketName, file_md5 + extName, file.getInputStream());
        //https://yjs-2109a.oss-cn-beijing.aliyuncs.com/oppo.png
        String endPoint1 = endpoint.replace("http://", "");
        String http_url = "https://"+ bucketName + "." + endPoint1 +"/" + file_md5 + extName;
        return Result.ok(http_url);
    }

    /**
     *	OSS断点续传
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/fileUploadCheckpoint")
    public Result<String> uploadFileByBreakingPoint(MultipartFile file) throws Throwable {
        ObjectMetadata meta = new ObjectMetadata();
        UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName,
                file.getOriginalFilename());
        File onFile = new File("d:\\01_2109A\\part\\" + file.getOriginalFilename());
        copyInputStreamToFile(file.getInputStream(), onFile);
        // 通过UploadFileRequest设置单个参数。
        // 填写本地文件的完整路径，例如D:\\localpath\\examplefile.txt。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
        uploadFileRequest.setUploadFile(onFile.getAbsolutePath());
        // 指定上传并发线程数，默认值为1。
        uploadFileRequest.setTaskNum(5);
        // 指定上传的分片大小，单位为字节，取值范围为100 KB~5 GB。默认值为100 KB。
        uploadFileRequest.setPartSize(100 * 1024);
        // 开启断点续传，默认关闭。
        uploadFileRequest.setEnableCheckpoint(true);
        // 记录本地分片上传结果的文件。上传过程中的进度信息会保存在该文件中，如果某一分片上传失败，再次上传时会根据文件中记录的点继续上传。上传完成后，该文件会被删除。
        // 如果未设置该值，默认与待上传的本地文件同路径，名称为${uploadFile}.ucp。
        //uploadFileRequest.setCheckpointFile(onFile.getAbsolutePath());
        // 文件的元数据。
        uploadFileRequest.setObjectMetadata(meta);
        // 设置上传回调，参数为Callback类型。
        //uploadFileRequest.setCallback("yourCallbackEvent");

        // 断点续传上传。
        ossClientBuilder.uploadFile(uploadFileRequest);
        String endPoint1 = endpoint.replace("http://", "");
        String http_url = "https://"+ bucketName + "." + endPoint1 +"/" + file.getOriginalFilename();
        return Result.ok(http_url);
    }



    /**
     * 流输出到文件的方法
     */
    private static void copyInputStreamToFile(InputStream inputStream,
                                              File file) throws IOException {

        try (FileOutputStream outputStream = new FileOutputStream(file)) {

            int read;
            byte[] bytes = new byte[1024];
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
        }
    }
}
